<script setup lang="ts">

import {reactive, ref} from "vue";
import {ElMessage, type UploadProps} from "element-plus";
import type {FaceSearchResult} from "@/types";
import {Plus} from "@element-plus/icons-vue";
import api from "@/api";
import RectImage from "@/components/RectImage.vue";

let faceSearchInfo = reactive({
  namespace: "namespace_1",
  collectionName: "collect_20211201_v11",
  imageBase64: "",
  confidenceThreshold: 0,
  faceScoreThreshold: 0,
  limit: 5,
  maxFaceNum: 5
})

let faceSearchResult = reactive<Array<FaceSearchResult>>([])
let display = ref(false)

const regs = {
  // 小写字母、数字和下划线
  name: /^[a-z0-9_]+$/,
  id: /^[a-zA-Z0-9]+$/,
  email: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/,
  number: /^([0]|[1-9][0-9]*)$/,
  password: /^(?=.*\d)(?=.*[a-zA-Z])[\da-zA-Z~!@#$%^&*_]{8,}$/,
  shareCode: /^[A-Za-z0-9]+$/
}


const rules = reactive({
  namespace: [
    {required: true, message: '请输入命名空间', trigger: 'blur'},
    {min: 1, max: 12, message: '长度在 1到 12 个字符', trigger: 'blur'},
    {pattern: regs.name, message: "请输入正确的格式，支持小写字母、数字和下划线", trigger: "blur"},
  ],
  collectionName: [
    {required: true, message: '请输入集合名称', trigger: 'blur'},
    {min: 1, max: 24, message: '长度在 1到 24 个字符', trigger: 'blur'},
    {pattern: regs.name, message: "请输入正确的格式，支持小写字母、数字和下划线", trigger: "blur"},
  ],
  imageBase64: [
    {required: true, message: '请输入图片', trigger: 'blur'}
  ]

})

const faceSearch = () => {
  display.value = false
  api.faceSearch(faceSearchInfo).then(res => {
    if(res.data.code === 0){

      let result = res.data.data
      for (let i = 0; i < result.length; i++) {
        let face = result[i]
        let match = face.match[0]
        for(let j = 0; j < face.match.length; j++){
          for(let k = j; k < face.match.length; k++){
            if(face.match[k].confidence > face.match[j].confidence){
              let temp = face.match[j]
              face.match[j] = face.match[k]
              face.match[k] = temp
            }
          }
        }
      }
      Object.assign(faceSearchResult,result)
      ElMessage.success(res.data.message)
      display.value = true
    }
  }).catch(err => {
    ElMessage.error(err.message)
  })
}

const getText = (item:any) => {
  let text = []
  text.push('人脸得分：'+item.match[0].faceScore.toFixed(2)+'%')
  text.push('相似度：'+item.match[0].confidence.toFixed(2)+'%')
  text.push(item.match[0].faceData[0].value)
  return text
}


const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  // 匹配rawFile 的类型是否是image
  if (!rawFile.type.includes('image')) {
    ElMessage.error('上传文件必须是图片')
    return false
  }
  const reader = new FileReader()
  reader.onload = function (e) {
    typeof reader.result === "string" ? faceSearchInfo.imageBase64 = reader.result : faceSearchInfo.imageBase64 = ''
  }
  reader.readAsDataURL(rawFile)
  return true
}

</script>

<template>
  <el-form :model="faceSearchInfo" label-width="auto" :rules="rules" ref="ruleFormRef" style="max-width: 100%">
    <el-form-item label="namespace（命名空间）：" prop="namespace">
      <el-input v-model="faceSearchInfo.namespace"/>
    </el-form-item>
    <el-form-item label="collectionName（集合名称）：" prop="collectionName">
      <el-input v-model="faceSearchInfo.collectionName"/>
    </el-form-item>
    <span style="padding-top: 90px;">人脸数据图片A：</span>
    <el-upload
        id="avatar-uploader"
        :show-file-list="false"
        :before-upload="beforeAvatarUpload"
    >
      <img v-if="faceSearchInfo.imageBase64" :src="faceSearchInfo.imageBase64" width="100" height="100"/>
      <el-icon v-else id="avatar-uploader-icon">
        <Plus/>
      </el-icon>
    </el-upload>
    <br>
    <span>人脸匹配分数阈值：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <el-slider v-model="faceSearchInfo.confidenceThreshold" show-input/>
    <br>
    <span>人脸质量分数阈值：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <el-slider v-model="faceSearchInfo.faceScoreThreshold" show-input/>
    <br>
    <span>图片中检索人脸数(默认5)：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <el-slider v-model="faceSearchInfo.maxFaceNum" show-input/>
    <br>
    <span>最大搜索条数(默认5)：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
    <el-slider v-model="faceSearchInfo.limit" show-input/>
    <br>
    <br>
    <el-button type="primary" @click="faceSearch" style="width: 300px">搜索</el-button>
  </el-form>
  <br>
  <span v-if="display">
  <RectImage
      :faceImage="faceSearchInfo.imageBase64"
      :rect="item.location"
      :text="getText(item)"
      v-for="(item,index) in faceSearchResult"
      :key="index"
  />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  </span>


</template>

<style scoped>
span {
  float: left;
}

.el-slider {
  max-width: 600px;
  display: flex;
  align-items: center;
}

#avatar-uploader {
  width: 100px;
  height: 100px;
  display: block;

  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

#avatar-uploader:hover {
  border-color: var(--el-color-primary);
}

#avatar-uploader-icon {
  font-size: 28px;
  color: #949494;
  width: 100px;
  height: 100px;
  text-align: center;
}

</style>